home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
browse2.zip
/
BROWSE.ASM
next >
Wrap
Assembly Source File
|
1991-02-24
|
16KB
|
508 lines
; BROWSE.ASM -- Full Screen File Pager
; ====================================
CSEG Segment
Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
Org 0080h
Parameter Label Byte
Org 0100h
Entry: Jmp Begin
; All Data
; --------
db 'ATTR='
Attribute db 0 ; Current screen attribute
db 'SHIFT='
ShiftHoriz db 8 ; Horizontal shift screen default
DosVersionFail db 'Requires DOS 2.0 or above$'
NoSpaceFail db 'Not enough memory$'
FileFail db 'File Not Found$'
ScreenFail db 'Unsupported video mode$'
Delimiters db 9,' ,;=/' ; Delimiters in parameter
FileHandle dw ? ; Use for saving file handle
WSMode db 0FFh ; AND value for non-WordStar mode
LineLength db ? ; Length of line (from BIOS)
NumberLines db 25,0 ; Number of lines (check EGA BIOS)
ScreenSize dw ? ; Size of screen in bytes
CheckRetrace db 1 ; Flag zero if EGA or MONO used
Addr6845 dw ? ; Could use for retrace check
ScreenAddr Label DWord ; Address of screen
ScreenOff dw 0 ; Higher for non-page 0
ScreenSeg dw 0B800h ; Set to B000h for Mono Mode 7
ScreenStart dw ? ; Points within buffer
EndOfFile dw ? ; Points within buffer
FileOffset dw -1, -1 ; Address within file of buffer data
HorizOffset dw 0 ; Horizontal offset for display
RightMargin dw 0 ; Right margin for offset display
Dispatch dw Home, Up, PgUp, Dummy, Left
dw Dummy, Right, Dummy, EndKEY, Down, PgDn
; Check DOS Version for 2.0 or above
; ----------------------------------
Begin: Cld ; All string directions forward
Mov AH,30h
Int 21h ; Get DOS Version Number
Cmp AL,2 ; Check for 2.0 or later
Jae DOSVerOK
Mov DX,Offset DOSVersionFail
ErrorExit: Mov AH,9 ; Write error message
Int 21h
Int 20h
; Parse Command Line to get File Name and WordStar flag
; -----------------------------------------------------
DOSVerOK: Mov SI,1 + Offset Parameter ; Points to parameter
NameSearch: Lodsb ; Get byte
Cmp AL,13 ; Check if carriage return
Jz NoFileFound ; If so, no file name
Mov DI,Offset Delimiters ; String of delimiters
Mov CX,5 ; Number of delimiters (no /)
Repne Scasb ; See if a match
Je NameSearch ; If a delimiter, keep looking
Mov DX,SI ; Otherwise found file name
Dec DX ; Points to beginning of it
EndSearch: Lodsb ; Get next byte
Cmp AL,13 ; See if carriage return
Je GotFileEnd ; If so, we're all done
Mov DI,Offset Delimiters ; String of delimiters
Mov CX,6 ; Number (including /)
Repne Scasb ; See if a match
Jne EndSearch ; If not, still in file name
Mov Byte Ptr [SI - 1],0 ; If so, mark end of file name
Jcxz GotFlag ; If slash, check for W
Jmp EndSearch ; Or continue flag search
GotFlag: Lodsb ; Get byte after / flag
Or AL,20h ; Uncapitalize
Cmp AL,'w' ; See if w for WordStar mode
Jnz GotFileEnd ; If not, just ignore it
Mov [WSMode],7Fh ; AND value for WordStar
; Open the File
; -------------
GotFileEnd: Mov Byte Ptr [SI - 1],0 ; Mark end of file name
; DX still points to name
Mov AX,3D00h ; Open file for reading
Int 21h ; by calling DOS
Jnc GotTheFile ; If no error, continue
NoFileFound: Mov DX,Offset FileFail ; Otherwise print a message
Jmp ErrorExit
GotTheFile: Mov [FileHandle],AX ; Save the file handle
; Get Screen Mode Information from BIOS Data Area
; -----------------------------------------------
Push ES ; Save register
Sub AX,AX
Mov ES,AX ; Set ES to 0 (BIOS Data)
Mov AL,ES:[0449h] ; Current Video Mode
;;;
CMP WORD PTR ES:[0463H],03D4H ; MONOCHROME EMULATION?
JZ CHK_IF_TEXT ; NO
MOV [SCREENSEG],0B000H ; ELSE ADDRESS MONO
MOV [CHECKRETRACE],0 ; NO RETR. CHECK NEEDED
CHK_IF_TEXT:
;;;
Cmp AL,3 ; Check if Color Alpha
Jbe DisplayOK ; Continue if so
Cmp AL,7 ; Check if monochrome display
Je Monochrome ; If so, branch
;;;
MOV AX,1A00H ; VGA-ONLY BIOS CALL: READ
INT 10H ; DISPLAY COMBINATION CODE
CMP AL,1AH ; VGA ADAPTER?
JNZ TO_SCREENFAIL ; NO, SORRY
MOV [CHECKRETRACE],0 ; ELSE NO RETRACE CHECK NEEDED
MOV DX,3CEH
MOV AL,6 ; READ BIT 0 OF THE VGA GRAPHICS
CLI ; CONTROLLER'S "MISCELLANEOUS"
OUT DX,AL ; REGISTER AT PORT 3CEh, INDEX
INC DX ; 6. IF BIT IS SET THEN WE'RE
JMP SHORT $+2 ; *REALLY* IN A GRAPHICS MODE
IN AL,DX ;
STI ;
TEST AL,1 ; WELL?
JZ DISPLAYOK ; OKAY, NOT SET = NOT GRAPHICS
TO_SCREENFAIL:
;;;
Mov DX,Offset ScreenFail ; We can't handle graphics
Jmp ErrorExit ; So print an error message
Monochrome: Mov [ScreenSeg],0B000h ; Use Monochrome Segment
Mov [CheckRetrace],0 ; Don't have to check retrace
DisplayOK: Mov AL,ES:[044Ah] ; Number of Columns
Mov [LineLength],AL ; Save it
Mov AX,ES:[044Eh] ; Offset into screen buffer
Mov [ScreenOff],AX ; Save it
Mov AX,ES:[0463h] ; Address of 6845 Regsiter
Mov [Addr6845],AX ; Save it
Push ES
Sub DL,DL ; Set Rows to zero first
Sub BH,BH
Mov AX,1130h ; EGA BIOS: Get Information
Int 10h
Pop ES
Or DL,DL ; Check if DL is still zero
Jz NoEGA ; If so, skip rest of stuff
Inc DL
Mov [NumberLines],DL ; Save Number of Lines
Test Byte Ptr ES:[0487h],4 ; Check if must check retrace
Jnz NoEGA
Mov [CheckRetrace],0 ; EGA says we don't have to
NoEGA: Mov BH,ES:[0462h] ; Get Current Page (use later)
Pop ES
Mov AL,[LineLength] ; Length of each line
Mul [NumberLines] ; Total chars on screen
Add AX,AX ; Double for attributes
Mov [ScreenSize],AX ; And Save it
; See if enough memory is left
; ----------------------------
Add AX,Offset ScreenHold ; Add ScreenSize to code end
Add AX,256 ; Add a little stack room
Cmp AX,SP ; Check against stack pointer
Jbe GotEnufMemory ; Continue if OK
Mov DX,Offset NoSpaceFail ; Otherwise end program
Jmp ErrorExit ; with error messae
; Get Current Screen Attribute
; ----------------------------
GotEnufMemory: Cmp [Attribute],0 ; Check if attribute pre-set
Jnz GotAttribute ; If so, move on
Mov DL,' ' ; Write out a byte
Mov AH,2 ; using DOS
Int 21h
Mov AL,8 ; Now backspace
Mov AH,14 ; using BIOS call
Int 10h
Mov AH,8 ; Read character & attribute
Int 10h ; using BIOS call (BH = pg)
Mov [Attribute],AH ; And save attribute
; Save Current Screen
; -------------------
GotAttribute: Mov DX,Offset Terminate ; Set Ctrl-Break exit
Mov AX,2523h ; to terminate that way
Int 21h
;;;
SAVE_CURSOR: MOV AH,0FH
INT 10H ; VIDEO PAGE INTO BH
MOV AH,3
INT 10H ; READ CURSOR POSITION
JMP SHORT SAVE_CURSOR_2
SAVED_CURSOR DW 0 ; STORAGE SPACE (A KLUDGE, I KNOW)
SAVE_CURSOR_2: MOV SAVED_CURSOR,DX
MOV AH,2
MOV DX,-1
INT 10H ; CURSOR TO TIMBUKTU FOR NOW
;;;
Mov DI,Offset ScreenHold ; Destination of screen
Mov CX,[ScreenSize] ; Size of screen
Push DS ; Save Source Segment
Lds SI,[ScreenAddr] ; Get screen address
Rep Movsb ; Move in the bytes
Pop DS ; Restore Source Segment
; Get Keyboard Key and Decide on Action
; -------------------------------------
Call Home ; Read file in
Mov [ScreenStart],SI ; Set buffer address
KeyLoop: Call UpDateScreen ; Write file to screen
GetKey: Mov AH,8 ; Get key
Int 21h ; by calling DOS
Cmp AL,27 ; Check if ESC
Je Terminate ; If so, terminate
Cmp AL,0 ; Check if extended
Jnz GetKey ; If not, try again
Mov AH,8 ; Get extended code
Int 21h ; by calling DOS
Sub AL,71 ; Subtract Home key value
Jb GetKey ; If below that, not valid
Cmp AL,(81 - 71) ; Check if above PgDn
Ja GetKey ; If so, ignore it
Sub AH,AH ; Zero out top byte
Add AX,AX ; Double for word access
Mov BX,AX ; Offset in dispatch table
Mov SI,[ScreenStart] ; Set current buffer pointer
Call [Dispatch + BX] ; Do the call
Mov [ScreenStart],SI ; Set new buffer pointer
Jmp KeyLoop ; And update the screen
; Terminate -- Restore screen and close file
; ------------------------------------------
Terminate: Mov SI,Offset ScreenHold ; Address of